using System;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
using System.Text.RegularExpressions;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using NGExtension;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace NGNntpExtension
{
	/// <summary>
	/// Summary description for Extension.
	/// </summary>
	public class Extension : NGExtension.INewsGatorExtension
	{
		#region Private Methods

		private void ProcessTheItemAfterwards(object reference, object postItem, object appObj)
		{
			if(reference is NntpPostInformation)
			{
				NntpPostInformation info = (NntpPostInformation) reference;

				// build the xml to be placed into the user defined property
				string xml = "<data><eworldnntp>";
				xml += "<messageid>" + System.Web.HttpUtility.HtmlEncode(info.Guid) + "</messageid>";
				xml += "<server>" + System.Web.HttpUtility.HtmlEncode(info.Server) + "</server>";
				xml += "<newsgroups>" + System.Web.HttpUtility.HtmlEncode(info.Newsgroups) + "</newsgroups>";
				xml += "<feedname>" + System.Web.HttpUtility.HtmlEncode(info.FeedName) + "</feedname>";
				xml += "</eworldnntp></data>";

				// get reference to the post item
				Outlook.PostItem thePostItem = (Outlook.PostItem) postItem;

				// retrieve the user properties
				Outlook.UserProperties props = thePostItem.UserProperties;

				Outlook.UserProperty userProp = null;
				foreach(Outlook.UserProperty prop in props)
				{
					// go through each of the user properties to find the PostCustomData property
					if(prop.Name == "PostCustomData")
					{
						// the PostCustomData property was found
						userProp = prop;
						break;
					}
				}
			
				if(userProp == null)
				{
					// the PostCustomData property was not found, add the user property
					userProp = props.Add("PostCustomData", Outlook.OlUserPropertyType.olText, true, 1);
					userProp.Value = "";
				}

				// set the value
				userProp.Value += xml;

				// release the user property
				System.Runtime.InteropServices.Marshal.ReleaseComObject(userProp);

				// release the post item
				System.Runtime.InteropServices.Marshal.ReleaseComObject(props);

				// save the post item
				thePostItem.Save();
			}
		}

		private object ProcessTheItemBefore(NGExtension.PostInfo postInfo, System.Xml.XmlNode originalItem, out bool createPost)
		{
			string guid = "";
			string server = "";
			string newsgroups = "";
			string feedName = "";

			if(postInfo.PostLink.ToLower().StartsWith("nntp://") || postInfo.PostLink.ToLower().StartsWith("news://"))
			{
				// this is a usenet post, process its information
				Regex rxLink = new Regex(@"(?<type>nntp|news)://(?<server>.*)/(?<newsgroup>.*)/(?<messageId>.*)", RegexOptions.Compiled);
				Regex rxNewsgroup = new Regex(@"Newsgroups:\s?(?<newsgroups>.*)");

				// set the feed name
				feedName = postInfo.FeedName;

				// retrieve the guid, server
				Match match = rxLink.Match(postInfo.PostLink);
				if(match.Groups.Count > 0)
				{
					guid = match.Groups["messageId"].Value;
					server = match.Groups["server"].Value;

					// attempt to remove the last character if it is not >
					if(guid.Substring(guid.Length - 1) != ">")
						guid = guid.Substring(0, guid.Length - 1);

				}
				else
				{
					// the data was not found, so set the values to empty
					guid = "";
					server = "";
				}

				// retrieve the newsgroups
				match = rxNewsgroup.Match(originalItem.OuterXml);
				if(match.Groups.Count > 0)
				{
					newsgroups = match.Groups["newsgroups"].Value.Trim();
				}
				else
				{
					newsgroups = "";
				}

				createPost = true;
				return new NntpPostInformation(guid, server, feedName, newsgroups);
			}
			else
			{
				createPost = true;
				return null;
			}
				
		}

		#endregion

		#region INewsGatorExtension Members

		public void BeginRetrieve()
		{
		}

		public void EndRetrieve()
		{
		}

		public void PostProcessItem(object reference, object postItem, object appObj)
		{
			ProcessTheItemAfterwards(reference, postItem, appObj);
		}

		public object PreProcessItem(NGExtension.PostInfo postInfo, System.Xml.XmlNode originalItem, out bool createPost)
		{
			return ProcessTheItemBefore(postInfo, originalItem, out createPost);
		}

		#endregion
	}
}
